#include <stdio.h>
#include <stdlib.h>
#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pthread.h> 

int wrong=0;
char test_data[5]={0,0xFF,0x55,0xAA,0};
int args[20][5]={};

void* do_test(void *arg);

int main()
{
	int i,flag=0;
	int thread_num=0;
	int times_num=0;
	int size=0;
	long threads[20]={};
	void *value[20]={};
	char tmp[30]={};
	char* memmory = (char *)malloc(0x100000);
	if(!memmory)
	{
		errno = EAGAIN;
		return -1;
	}

	while(1)
	{
		printf(">>>");
		fflush(stdout);
		
		scanf(" %s",tmp);
		
		if(!strcmp(tmp,"times"))
		{
			scanf(" %d",&times_num);
			if(times_num < 0 || times_num > 0x0FFFFFF)
	     	{
				 printf("测试次数超过正常范围\n");
				 times_num = 0;
				 errno = EINVAL;
				 if(flag%10==1)
				     flag--;
				 continue;
			}
			printf("测试次数为: %d\n",times_num);
			if(flag%10==0)
				flag++;
			continue;
		}
		
		if(!strcmp(tmp,"thread"))
		{	
			scanf(" %d",&thread_num);
			if(thread_num < 0 || thread_num > 20)
			{
				 printf("测试线程数超过正常范围\n");
				 times_num = 0;
				 errno = EINVAL;
				 if(flag%100==10 || flag%100 ==11)
				     flag = flag-10;
				 continue;
			}
			printf("测试线程数为: %d\n",thread_num);
            size = 0x100000 / thread_num;
			for(i=0;i<thread_num;i++)
			{
				args[i][0] = (int)memmory + i*size;
				args[i][1] = size;
				args[i][4] = 0;
			}
			args[i-1][1] = size+(0x100000%thread_num);
			if(flag%100 < 10)
				flag = flag+10;
			continue;
		}

		if(!strcmp(tmp,"go"))
		{
			if(flag%100 == 11)
			{
				for(i=0;i<thread_num;i++)
				{
					args[i][2] = times_num;
					args[i][3] = 0;
					pthread_create(&threads[i],NULL,(void *)do_test,(void *)(args[i]));
				}
				flag = (flag%100) +100;
				continue;
			}
			else
			{
				printf("缺少参数\n");
				errno = EINVAL;
				for(i=0;i<thread_num;i++)
				{
					args[i][3] = 0;
					args[i][4] = 0;
				}
				continue;
			}
		}

		if(!strcmp(tmp,"status"))
		{
			if(flag >= 100)
			{
				for(i=0;i<thread_num;i++)
				{
					if(args[i][1] == args[i][3] || args[i][4] == 1)
						printf("Thread %d has exited.(%08X-%08X, %d/%d)\n",i,(args[i][0]-(int)memmory),(args[i][0]+args[i][1]-(int)memmory-1),args[i][3],args[i][1]);
			        else if(args[i][3] >= 0)
						printf("Thread %d is running.(%08X-%08X, %d/%d)\n",i,args[i][0]-(int)memmory,args[i][0]+args[i][1]-(int)memmory-1,args[i][3],args[i][1]);
	            }
				continue;
			}
			else if(flag%100 >= 10)
			{
				for(i=0;i<thread_num;i++)
				    printf("Thread %d has exited.(00000000-000FFFFF, 0/1048575)\n",i);
				continue;
			}
		}

		if(!strcmp(tmp,"abort"))
		{
			if(flag>=100)
			{
				for(i=0;i<thread_num;i++)
				    args[i][4] = 1;
			    continue;
			}
		}

		if(!strcmp(tmp,"exit"))
		{
			if(flag>=100 && (flag%100)>=10)
			{
				for(i=0;i<thread_num;i++)
				    args[i][4] = 1;		    
				for(i=0;i<thread_num;i++)
					pthread_join(threads[i],&value[i]);
			    return 0;
			}
			return 0;
		}
	}

	return 0;
}

void* do_test(void *arg)
{
	int i,j,k;
	int id;
	int *myarg = NULL;
	char *start = NULL;

	myarg = (int *)arg;
	start = (char *)(myarg[0]);
	id = (int)start / myarg[2];
	test_data[4] = (char)rand();
	
	for(i=0;i<myarg[1];i++)
	{
		for(j=0;j<myarg[2];j++)
		{
			for(k=0;k<5;k++)
			{
				*start = test_data[k];
				if((*start) != test_data[k])
					wrong=1;
			}
		}
		if(myarg[4] == 1)
			pthread_exit(&wrong);
		myarg[3]++;
		start++;
	}
	
	pthread_exit(&wrong);
	return 0;
}
			
					
		
			
		


			
	